import { keypointDef, limbSeq, limbColors } from './const'
import Konva from 'konva'
import { debounce } from 'lodash-es'
export default class KonvaImage {
  el: any // 容器dom对象
  container: any // 容器大小{width,height,imgWidth,imgHeight}
  scale: number // 缩放比例
  stage: any // Konva.Stage对象
  imgLayer: any // Konva.Layer底图layer
  layer: any // Konva.Layer标注layer
  bboxes: any // bboxes数据
  currentGroup: any // 当前高亮组
  currentPoint: any // 当前选中的点
  currentRect: any // 当前选中的矩形
  tooltip: any // 悬浮提示信息
  kptsNames: any // keypoints中文名
  currentPointer: any // 当前选中点的坐标，用于判断是否有移动过
  transformer: any // 调整矩形变换框
  events: any // 事件
  drawState: any // 画图对象

  constructor(el: any, src?: string) {
    this.el = el
    this.scale = 1 // 缩放
    this.container = {}
    this.events = {}
    this.drawState = {
      drawType: '', // 绘制图形类型，rect，line，polygon，point
      currentDrawShape: null, // 当前正在画的图形
      isDrawing: false, // 是否正在绘制图形
      startX: 0, // 画图开始坐标
      startY: 0 // 画图开始坐标
    }
    if (src) {
      this.loadImage(src)
    }
    this.initResize(this.el)
    this.debounceKeyMove = debounce(this.debounceKeyMove, 500).bind(this)
  }

  // keypoints中文名
  setKptsNames(kptsNames) {
    this.kptsNames = kptsNames
  }

  // 设置事件
  setEvents(events) {
    Object.assign(this.events, events)
  }

  // 设置绘制类型
  setDrawType(type) {
    if (type) {
      this.stage.setAttr('draggable', false)
    }
    this.drawState.drawType = type
  }

  // 设置bboxes数据
  setBboxes(bboxes: any) {
    if (this.layer) {
      this.layer.clear()
    }
    this.bboxes = bboxes
    if (this.layer) {
      this.bboxes.forEach((box: any) => {
        // 添加一个分组
        const group = new Konva.Group({
          // draggable: true,
          originData: box,
          name: 'group'
        })
        this.layer.add(group)

        const { x1 = 0, y1 = 0, x2 = 0, y2 = 0, keypoints = {} } = box
        // box框
        const rect = new Konva.Rect({
          cls_id: box.cls_id,
          name: 'rect',
          x: x1,
          y: y1,
          width: x2 - x1,
          height: y2 - y1,
          stroke: 'black',
          strokeWidth: 1 / this.scale,
          draggable: true
        })
        group.add(rect)
        rect.moveToBottom()

        // 每个关节点只渲染一个点
        const usedkeys = {}

        // 关节点
        limbSeq.forEach(([x, y], i) => {
          const from = keypoints[keypointDef[x].name]
          const to = keypoints[keypointDef[y].name]
          const color = this.getBGR(limbColors[i])
          if (from?.x && from?.y && to?.x && to?.y) {
            // 关节点连线
            const line = new Konva.Line({
              name: 'line',
              pointKey: [keypointDef[x].name, keypointDef[y].name],
              points: [from.x, from.y, to.x, to.y],
              stroke: color,
              strokeWidth: 2 / this.scale
            })
            group.add(line)
          }
          if (from?.x && from?.y && !usedkeys[keypointDef[x].name]) {
            // 关节点点位
            const circle = new Konva.Circle({
              originData: { ...from, color },
              name: 'circle',
              pointKey: keypointDef[x].name,
              x: from.x,
              y: from.y,
              radius: 2 / this.scale,
              fill: from?.visible == 1 ? '#fff' : color,
              stroke: color,
              strokeWidth: 1 / this.scale,
              draggable: true
            })
            group.add(circle)
            usedkeys[keypointDef[x].name] = true
            circle.moveToTop()
          }
          if (to?.x && to?.y && !usedkeys[keypointDef[y].name]) {
            // 关节点点位
            const circle = new Konva.Circle({
              originData: { ...to, color },
              name: 'circle',
              pointKey: keypointDef[y].name,
              x: to.x,
              y: to.y,
              radius: 2 / this.scale,
              fill: to?.visible == 1 ? '#fff' : color,
              stroke: color,
              strokeWidth: 1 / this.scale,
              draggable: true
            })
            group.add(circle)
            usedkeys[keypointDef[y].name] = true
            circle.moveToTop()
          }
        })

        group.children
          ?.filter((c) => c.getAttr('name') === 'circle')
          .forEach((circle) => {
            circle.zIndex(0)
            circle.on('mouseenter', (e) => {
              if (this.currentGroup && e.target.getParent() != this.currentGroup) {
                return
              }
              if (this.tooltip) {
                this.tooltip.position({
                  x: e.target.attrs.x + 10 / this.scale,
                  y: e.target.attrs.y + 10 / this.scale
                })
                const text = this.tooltip.children.find((x) => x.getAttr('name') === 'text')
                const rect = this.tooltip.children.find((x) => x.getAttr('name') === 'rect')
                text.text(
                  this.kptsNames?.[e.target.getAttr('pointKey')]?.zh_cn ||
                    e.target.getAttr('pointKey')
                )
                rect.width(text.width())
                this.tooltip.show()
                this.tooltip.moveToTop()
              }
            })
            circle.on('mouseout', () => {
              if (this.tooltip) {
                this.tooltip.hide()
              }
            })
            circle.on('dragmove', (e) => {
              if (this.tooltip) {
                this.tooltip.position({
                  x: e.target.attrs.x + 10 / this.scale,
                  y: e.target.attrs.y + 10 / this.scale
                })
              }
            })
          })
        group.children
          ?.filter((c) => c.getAttr('name') === 'line')
          .forEach((c) => {
            c.zIndex(1)
          })
        group.children
          ?.filter((c) => c.getAttr('name') === 'rect')
          .forEach((c) => {
            c.zIndex(2)
          })
      })
    }
  }

  // 加载底图
  async loadImage(url: string) {
    return new Promise((resolve) => {
      const img = new Image()
      img.onload = () => {
        const rect = this.el.getBoundingClientRect()
        this.container.imgWidth = img.naturalWidth
        this.container.imgHeight = img.naturalHeight

        if (rect.width / rect.height < this.container.imgWidth / this.container.imgHeight) {
          this.container.width = rect.width
          this.container.height = (rect.width * this.container.imgHeight) / this.container.imgWidth
        } else {
          this.container.height = rect.height
          this.container.width = (rect.height * this.container.imgWidth) / this.container.imgHeight
        }
        this.scale = this.container.width / this.container.imgWidth || 1
        this.initKonva(img)
        resolve(img)
      }
      img.src = url
    })
  }

  // 获取相对于当前变换后 Stage 的鼠标位置
  getRelativePointerPosition() {
    // 获取 Stage 的变换信息
    const transform = this.stage.getAbsoluteTransform().copy()
    // 反转变换矩阵，以便将鼠标位置转换到 Stage 的局部坐标系
    transform.invert()

    // 获取鼠标相对于 Stage 容器的位置
    const pos = this.stage.getPointerPosition()
    if (!pos) return { x: 0, y: 0 }

    // 应用变换矩阵
    return transform.point(pos)
  }

  // 初始化canvas
  initKonva(img: any) {
    if (this.stage) {
      this.stage.destroy()
    }
    document.onkeydown = null
    this.stage = new Konva.Stage({
      container: this.el,
      width: this.container.imgWidth,
      height: this.container.imgHeight,
      draggable: true
    })
    console.log(this.container, this.scale)

    const scale = this.container.width / this.container.imgWidth || 1 // 计算缩放比例
    this.scale = scale
    this.stage.width(this.container.width) // 设置舞台宽度为容器宽度
    this.stage.height(this.container.height) // 根据缩放比例设置舞台高度
    this.stage.scale({ x: scale, y: scale }) // 设置舞台缩放比例

    this.layer = new Konva.Layer()
    const imgLayer = new Konva.Layer()
    this.stage.add(imgLayer)
    const yoda = new Konva.Image({
      x: 0,
      y: 0,
      image: img,
      width: this.container.imgWidth,
      height: this.container.imgHeight
    })
    imgLayer.add(yoda)
    imgLayer.draw()
    this.imgLayer = imgLayer
    this.stage.add(this.layer)

    this.initTooltip()

    this.stage.on('contextmenu', (e) => {
      e.evt.preventDefault()
      e.evt.stopPropagation()
    })

    this.stage.on('wheel', (e: any) => {
      e.evt.preventDefault()
      e.evt.stopPropagation()
      const isPressKey = e.evt.shiftKey || e.evt.metaKey || e.evt.ctrlKey || e.evt.altKey
      const direction = (e.evt.deltaY > 0 ? -0.01 : 0.01) * (isPressKey ? 25 : 5)
      this.scale = this.scale + direction
      this.container.scale = this.scale
      if (this.scale < 0.1) {
        this.scale = 0.1
        return
      }
      if (this.scale > 10) {
        this.scale = 10
        return
      }
      this.stage.scaleX(this.scale)
      this.stage.scaleY(this.scale)
      this.stage.x(
        -(
          (this.stage.getPointerPosition().x - this.stage.x()) *
            (this.scale / (this.scale - direction)) -
          this.stage.getPointerPosition().x
        )
      )
      this.stage.y(
        -(
          (this.stage.getPointerPosition().y - this.stage.y()) *
            (this.scale / (this.scale - direction)) -
          this.stage.getPointerPosition().y
        )
      )
      this.layer
        .find('Group')
        .filter((g) => g.getAttr('name') === 'group')
        .forEach((g) => {
          g.children.forEach((c) => {
            if (c.getAttr('name') === 'rect') {
              c.setAttr('strokeWidth', 1 / this.scale)
            } else if (c.getAttr('name') === 'line') {
              c.setAttr('strokeWidth', (g === this.currentGroup ? 3 : 2) / this.scale)
            } else if (c.getAttr('name') === 'circle') {
              c.setAttr('strokeWidth', 1 / this.scale)
              if (c === this.currentPoint) {
                c.setAttr('radius', 7 / this.scale)
              } else {
                c.setAttr('radius', (g === this.currentGroup ? 5 : 2) / this.scale)
              }
            }
          })
        })
      const tooltipText = this.tooltip.children.find((x) => x.getAttr('name') === 'text')
      const tooltipRect = this.tooltip.children.find((x) => x.getAttr('name') === 'rect')
      tooltipText.setAttr('fontSize', 16 / this.scale)
      tooltipText.setAttr('padding', 5 / this.scale)
      tooltipRect.width(tooltipText.width())
      tooltipRect.height(tooltipText.height())
      tooltipRect.setAttrs({
        strokeWidth: 2 / this.scale,
        shadowBlur: 5 / this.scale,
        shadowOffsetX: 5 / this.scale,
        shadowOffsetY: 5 / this.scale,
        cornerRadius: 5 / this.scale
      })
    })
    this.initMouseEvent()
    this.stage.batchDraw()
  }

  initTooltip() {
    const tooltipLayer = new Konva.Layer()
    this.stage.add(tooltipLayer)
    this.tooltip = new Konva.Group()
    const text = new Konva.Text({
      name: 'text',
      text: '',
      fontSize: 16 / this.scale,
      fontFamily: 'Calibri',
      fill: '#555',
      padding: 5 / this.scale,
      align: 'left'
    })
    const rect = new Konva.Rect({
      name: 'rect',
      stroke: '#555',
      strokeWidth: 2 / this.scale,
      fill: '#ddd',
      width: text.width(),
      height: text.height(),
      shadowColor: 'black',
      shadowBlur: 5 / this.scale,
      shadowOffsetX: 5 / this.scale,
      shadowOffsetY: 5 / this.scale,
      shadowOpacity: 0.2,
      cornerRadius: 5 / this.scale
    })
    this.tooltip.add(rect)
    this.tooltip.add(text)
    this.tooltip.hide()
    tooltipLayer.add(this.tooltip)
  }

  debounceKeyMove() {
    if (this.currentPoint) {
      const pointKey = this.currentPoint.getAttr('pointKey')
      const lines = this.currentGroup.children.filter(
        (x: any) => x.getAttr('name') === 'line' && x.getAttr('pointKey')?.includes(pointKey)
      )
      lines.forEach((line) => {
        const pointKeys = line.getAttr('pointKey') || []
        const points = line.getAttr('points')
        if (pointKeys.findIndex((x) => x === pointKey) === 0) {
          points[0] = this.currentPoint.attrs.x
          points[1] = this.currentPoint.attrs.y
        } else if (pointKeys.findIndex((x) => x === pointKey) === 1) {
          points[2] = this.currentPoint.attrs.x
          points[3] = this.currentPoint.attrs.y
        }
        line.setAttrs({
          points
        })
      })
    }
    // 移动超过1像素，算是移动
    if (typeof this.events?.moved === 'function') {
      this.events?.moved()
    }
  }

  keydownEvent(e) {
    console.log(e.code)
    console.log('--->>', this.currentGroup)
    const currentShape = this.currentPoint || this.currentRect
    if (!currentShape) {
      return
    }
    const isPressKey = e.shiftKey || e.metaKey || e.ctrlKey || e.altKey
    switch (e.code) {
      case 'ArrowRight':
        currentShape.setAttr('x', currentShape.attrs.x + (isPressKey ? 10 : 1))
        this.debounceKeyMove()
        break
      case 'ArrowLeft':
        currentShape.setAttr('x', currentShape.attrs.x - (isPressKey ? 10 : 1))
        this.debounceKeyMove()
        break
      case 'ArrowDown':
        currentShape.setAttr('y', currentShape.attrs.y + (isPressKey ? 10 : 1))
        this.debounceKeyMove()
        break
      case 'ArrowUp':
        currentShape.setAttr('y', currentShape.attrs.y - (isPressKey ? 10 : 1))
        this.debounceKeyMove()
        break
      case 'Backspace':
      case 'Delete':
        if (this.currentRect) {
          this.currentRect.getParent().destroy()
          this.currentRect = null
          this.currentGroup = null
          this.currentBoxChange()
          if (this.transformer) {
            this.transformer.destroy()
            this.transformer = null
          }
          // 修改后，直接保存
          if (typeof this.events?.moved === 'function') {
            this.events?.moved()
          }
        }
        break
      case 'KeyV':
        const originData = this.currentPoint.getAttr('originData')
        const visible = originData.visible == 1 ? 2 : 1
        this.currentPoint.setAttr('fill', visible == 1 ? '#fff' : originData.color)
        this.currentPoint.setAttr('originData', {
          ...originData,
          visible
        })
        // 修改后，直接保存
        if (typeof this.events?.moved === 'function') {
          this.events?.moved()
        }
        break
    }
  }

  // 初始化鼠标事件
  initMouseEvent() {
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    const me = this
    this.stage.on('mousedown', function (e) {
      const parent = e.target.getParent()
      me.clearSelectStroke()
      // 点击图层组
      if (parent && parent.getType() === 'Group') {
        me.stage.setAttr('draggable', false)
        me.currentGroup = parent
        me.currentGroup.moveToTop()
        me.currentGroup.children.forEach((c) => {
          if (c.getAttr('name') === 'rect') {
            c.setAttr('stroke', 'red')
          } else if (c.getAttr('name') === 'line') {
            c.setAttr('strokeWidth', 3 / me.scale)
          } else if (c.getAttr('name') === 'circle') {
            // c.moveToTop()
            c.setAttr('strokeWidth', 1 / me.scale)
            c.setAttr('radius', (c === me.currentPoint ? 7 : 5) / me.scale)
          }
        })
        me.stage.setAttr('draggable', false)

        me.currentGroup.children
          ?.filter((c) => c.getAttr('name') === 'circle')
          .forEach((circle) => {
            circle.zIndex(0)
          })
        me.currentGroup.children
          ?.filter((c) => c.getAttr('name') === 'line')
          .forEach((c) => {
            c.zIndex(1)
          })
        me.currentGroup.children
          ?.filter((c) => c.getAttr('name') === 'rect')
          .forEach((c) => {
            c.zIndex(2)
          })

        if (me.transformer) {
          // 检测是否点击了 Transformer 的控制点
          const anchor = me.transformer.children.find((x) => x == e.target)
          if (anchor) {
            console.log('点击了控制点', anchor)
            // 根据 anchor 可以知道点击的是哪个控制点
            // anchor.getClassName() 会返回 'top-left', 'top-center', 'top-right' 等
            return // 如果是控制点，不执行后续逻辑
          }
          if (
            !me.currentGroup.children
              ?.filter((c) => c.getAttr('name') === 'rect')
              .some((c) => me.transformer.children?.some((t) => t == c))
          ) {
            me.transformer.destroy()
            me.transformer = null
          }
        }
        // 获取焦点时，添加矩形转换
        if (!me.transformer) {
          const rect = me.currentGroup.children.find((c) => c.getAttr('name') === 'rect')
          const tr = new Konva.Transformer({
            borderStroke: '#000', // 虚线颜色
            // borderStrokeWidth: 1, //虚线大小
            // borderDash: [5], // 虚线间距
            keepRatio: false, // 不等比缩放
            rotationSnaps: [0, 90, 180, 270],
            rotationSnapTolerance: 2,
            rotateEnabled: false,
            anchorSize: 8,
            anchorCornerRadius: 8
          })
          me.layer.add(tr)
          tr.nodes([rect])
          rect.on('transformend', function () {
            const isScaled =
              Math.abs(rect.scaleX() - 1) > 0.01 || Math.abs(rect.scaleY() - 1) > 0.01
            rect.width(rect.width() * rect.scaleX())
            rect.height(rect.height() * rect.scaleY())
            rect.scaleX(1)
            rect.scaleY(1)
            if (isScaled) {
              me.events?.moved()
            }
          })
          me.transformer = tr
        }
      } else {
        if (me.drawState.drawType == 'rect' && !me.drawState.currentDrawShape) {
          me.stage.setAttr('draggable', false)
          me.drawState.isDrawing = true
          const pos = me.getRelativePointerPosition()
          const x = pos.x,
            y = pos.y
          me.drawState.startX = x
          me.drawState.startY = y
          const newRect = new Konva.Rect({
            x,
            y,
            width: 0,
            height: 0,
            stroke: 'black',
            strokeWidth: 1 / me.scale,
            name: 'rect',
            draggable: true,
            perfectDrawEnabled: false,
            dragBoundFunc: function (pos) {
              return pos
            }
          })
          me.layer.add(newRect)
          me.drawState.currentDrawShape = newRect
        } else {
          me.currentGroup = null
          me.stage.setAttr('draggable', true)
          // 失去焦点时，删除矩形转换
          if (me.transformer) {
            me.transformer.destroy()
            me.transformer = null
          }
        }
        document.onkeydown = null
      }
      if (me.currentPoint) {
        me.currentPoint.setAttr('radius', 5 / me.scale)
        me.currentPoint.setAttr('stroke', me.currentPoint.getAttr('originData')?.color)
      }
      if (e.target.getAttr('name') === 'circle') {
        me.currentPoint = e.target
        me.currentPointer = { x: me.currentPoint.attrs.x, y: me.currentPoint.attrs.y }
        me.currentPoint.setAttr('radius', 7 / me.scale)
        me.currentPoint.setAttr('stroke', 'yellow')
        me.currentPoint.moveToTop()
        document.onkeydown = (e) => me.keydownEvent(e)
        me.currentRect = null
      } else if (e.target.getAttr('name') === 'rect') {
        me.currentRect = e.target
        me.currentPointer = { x: me.currentRect.attrs.x, y: me.currentRect.attrs.y }
        me.currentRect.moveToTop()
        document.onkeydown = (e) => me.keydownEvent(e)
        me.currentPoint = null
      } else {
        me.currentPoint = null
        me.currentRect = null
      }
      me.currentBoxChange()
    })

    // 鼠标移动事件 - 调整矩形大小
    this.stage.on('mousemove', function () {
      if (!me.drawState.isDrawing) return
      const pos = me.getRelativePointerPosition()
      const x = pos.x
      const y = pos.y
      me.drawState.currentDrawShape.width(x - me.drawState.startX)
      me.drawState.currentDrawShape.height(y - me.drawState.startY)

      me.layer.batchDraw()
    })

    this.stage.on('mouseup', function () {
      if (me.drawState.isDrawing) {
        me.drawState.isDrawing = false
        // 如果矩形太小，则移除
        if (
          me.drawState.currentDrawShape.width() < 5 ||
          me.drawState.currentDrawShape.height() < 5
        ) {
          me.drawState.currentDrawShape.destroy()
          me.layer.draw()
        } else {
          const group = new Konva.Group({
            // draggable: true,
            originData: null,
            name: 'group'
          })
          me.layer.add(group)
          group.add(me.drawState.currentDrawShape)
          me.drawState.currentDrawShape.moveToBottom()
        }
        me.drawState = {
          drawType: me.drawState.drawType,
          currentDrawShape: null,
          isDrawing: false,
          startX: 0,
          startY: 0
        }
        // 移动超过1像素，算是移动
        if (typeof me.events?.drawEnd === 'function') {
          me.setDrawType('')
          me.events?.drawEnd()
        }
      }

      if (me.currentPoint && me.currentGroup) {
        const pointKey = me.currentPoint.getAttr('pointKey')
        const lines = me.currentGroup.children.filter(
          (x: any) => x.getAttr('name') === 'line' && x.getAttr('pointKey')?.includes(pointKey)
        )
        lines.forEach((line) => {
          const pointKeys = line.getAttr('pointKey') || []
          const points = line.getAttr('points')
          if (pointKeys.findIndex((x) => x === pointKey) === 0) {
            points[0] = me.currentPoint.attrs.x
            points[1] = me.currentPoint.attrs.y
          } else if (pointKeys.findIndex((x) => x === pointKey) === 1) {
            points[2] = me.currentPoint.attrs.x
            points[3] = me.currentPoint.attrs.y
          }
          line.setAttrs({
            points
          })
        })
        console.log(lines)
        // 移动超过1像素，算是移动
        if (
          (Math.abs(me.currentPointer.x - me.currentPoint.attrs.x) >= 1 ||
            Math.abs(me.currentPointer.y - me.currentPoint.attrs.y) >= 1) &&
          typeof me.events?.moved === 'function'
        ) {
          me.events?.moved()
        }
      } else if (me.currentRect && me.currentGroup) {
        // 移动超过1像素，算是移动
        if (
          (Math.abs(me.currentPointer.x - me.currentRect.attrs.x) >= 1 ||
            Math.abs(me.currentPointer.y - me.currentRect.attrs.y) >= 1) &&
          typeof me.events?.moved === 'function'
        ) {
          me.events?.moved()
        }
      } else {
        me.clearSelectStroke()
      }
      me.currentPointer = {}
    })
  }

  currentBoxChange() {
    if (typeof this.events?.currentBoxChange === 'function') {
      this.events?.currentBoxChange(this.currentRect)
    }
  }

  // 取消选择状态
  clearSelectStroke() {
    const groups = (this.layer?.find('Group') || []).filter((g) => g.getAttr('name') === 'group')
    groups.forEach((g) => {
      g.children.forEach((c) => {
        if (c.getAttr('name') === 'rect') {
          c.setAttr('stroke', 'black')
        } else if (c.getAttr('name') === 'line') {
          c.setAttr('strokeWidth', 2 / this.scale)
        } else if (c.getAttr('name') === 'circle') {
          c.setAttr('strokeWidth', 2 / this.scale)
          c.setAttr('radius', 2 / this.scale)
          c.setAttr('stroke', c.getAttr('originData')?.color)
        }
      })
    })
  }

  // 窗口缩放事件
  initResize(el: any) {
    const resizeObserver = new ResizeObserver(async () => {
      if (this.stage) {
        await new Promise((resolve) => {
          setTimeout(() => {
            resolve(true)
          }, 100)
        })
        const rect = el.getBoundingClientRect()
        if (rect.width / rect.height < this.container.imgWidth / this.container.imgHeight) {
          this.container.width = rect.width
          this.container.height = (rect.width * this.container.imgHeight) / this.container.imgWidth
        } else {
          this.container.height = rect.height
          this.container.width = (rect.height * this.container.imgWidth) / this.container.imgHeight
        }
        const scale = this.container.width / this.container.imgWidth || 1
        this.scale = scale
        this.stage.x(0)
        this.stage.y(0)
        this.stage.scale({ x: scale, y: scale })
        this.stage.width(this.container.width)
        this.stage.height(this.container.height)
      }
    })
    resizeObserver.observe(el)
  }

  // 返回keypoints数据
  getBboxes() {
    const groups = (this.layer?.find('Group') || []).filter((g) => g.getAttr('name') === 'group')
    return groups.map((g) => {
      // const originData = g.getAttr('originData')
      const rect = g.children?.find((c) => c.getAttr('name') === 'rect')
      const keypoints = g.children
        ?.filter((c) => c.getAttr('name') === 'circle')
        .reduce((t, c) => {
          t[c.getAttr('pointKey')] = {
            x: Number(c.attrs.x.toFixed(4)),
            y: Number(c.attrs.y.toFixed(4)),
            visible: c.getAttr('originData')?.visible
          }
          return t
        }, {})
      return {
        // ...originData,
        x1: Number(rect.attrs.x.toFixed(4)),
        y1: Number(rect.attrs.y.toFixed(4)),
        x2: Number((rect.attrs.x + rect.width()).toFixed(4)),
        y2: Number((rect.attrs.y + rect.height()).toFixed(4)),
        cls_id: rect.getAttr('cls_id'),
        keypoints
      }
    })
  }

  clear() {
    this.layer.clear()
  }

  // bgr转rgb
  getBGR(bgr: any) {
    if (bgr) {
      const [b, g, r] = bgr
      return `rgb(${r},${g},${b})`
    }
    return 'rgb(255,255,0)'
  }
  // rgb对象
  getRGB(rgb: any) {
    if (rgb) {
      const { r = 0, g = 0, b = 0 } = rgb
      return `rgb(${r},${g},${b})`
    }
    return 'rgb(255,255,0)'
  }
}
